#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <list>
#include <arpa/inet.h>
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_CommHdr.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_Types.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_ProtocolHdr.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_HelpComponents/HelpComponents_Packets/Packets_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_HelpComponents/HelpComponents_Packets/Packets_Error.h"

//g++ -std=gnu++11 -Wall -g Test_Packets.cpp -o Test_Packets -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_HelpComponents -lNetEngine_BaseLib -lHelpComponents_Packet -Wl,-rpath=../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_HelpComponents,--disable-new-dtags

int Test_Packets()
{
    SOCKET hSocket = 100;
    XNETHANDLE xhPacket;
    if (!HelpComponents_Packets_Init(&xhPacket))
    {
        printf("HelpComponents_Packets_Init:%lX\n", Packets_GetLastError());
        return -1;
    }
    if (!HelpComponents_Packets_CreateEx(xhPacket, hSocket))
    {
        printf("HelpComponents_Packets_CreateEx:%lX\n", Packets_GetLastError());
        return -1;
    }

    TCHAR tszMsgBuffer[2048];
    LPCTSTR lpszMsgBuffer = _T("hello");
    NETENGINE_PROTOCOLHDREX st_ProtocolHdr;
    NETENGINE_PROTOCOLTAILEX st_ProtocolTail;
    int nLen = _tcslen(lpszMsgBuffer);
    int nMsgLen = 0;

    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(NETENGINE_PROTOCOLHDREX));
    memset(&st_ProtocolTail, '\0', sizeof(NETENGINE_PROTOCOLTAILEX));

    st_ProtocolHdr.wHeader = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER;
    st_ProtocolHdr.wVersion = 1;
    st_ProtocolHdr.wPayload = 2;
    st_ProtocolHdr.xhToken = hSocket;
    st_ProtocolHdr.xhXTPTime = 1;
    st_ProtocolHdr.unOperatorType = ENUM_ENGINE_COMMUNICATION_PROTOCOL_TYPE_NORMAL;
    st_ProtocolHdr.unOperatorCode = NETENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_ISOK;
    st_ProtocolHdr.unPacketSize = 5;
    st_ProtocolHdr.wIsReply = FALSE;

    st_ProtocolTail.wCheckSum = HelpComponents_Help_CheckSum(lpszMsgBuffer, nLen);
    st_ProtocolTail.wTail = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL;

    memcpy(tszMsgBuffer, &st_ProtocolHdr, sizeof(NETENGINE_PROTOCOLHDREX));
    memcpy(tszMsgBuffer + sizeof(NETENGINE_PROTOCOLHDREX), lpszMsgBuffer, nLen);
    memcpy(tszMsgBuffer + sizeof(NETENGINE_PROTOCOLHDREX) + nLen, &st_ProtocolTail, sizeof(NETENGINE_PROTOCOLTAILEX));

    nMsgLen = sizeof(NETENGINE_PROTOCOLHDREX) + sizeof(NETENGINE_PROTOCOLTAILEX) + nLen;

    HelpComponents_Packets_PostEx(xhPacket, hSocket, tszMsgBuffer, 10);
    HelpComponents_Packets_PostEx(xhPacket, hSocket, tszMsgBuffer + 10, 15);
    HelpComponents_Packets_PostEx(xhPacket, hSocket, tszMsgBuffer + 25, 10);

    nMsgLen = 2048;
    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(NETENGINE_PROTOCOLHDREX));

    HelpComponents_Packets_WaitEventEx(xhPacket);
    HelpComponents_Packets_GetEx(xhPacket, hSocket, tszMsgBuffer, &nMsgLen, &st_ProtocolHdr);

    printf("%d=%s\n", nMsgLen, tszMsgBuffer);
    HelpComponents_Packets_DeleteEx(xhPacket, hSocket);
    HelpComponents_Packets_Destory(xhPacket);
    return 0;
}
int Test_Datas()
{
    XNETHANDLE xhPacket;
    LPCTSTR lpszClientAddr = _T("127.0.0.1");
    if (!HelpComponents_Datas_Init(&xhPacket))
    {
        printf("HelpComponents_Datas_Init:%lX\n", Packets_GetLastError());
        return -1;
    }
    if (!HelpComponents_Datas_CreateEx(xhPacket, lpszClientAddr))
    {
        printf("HelpComponents_Datas_CreateEx:%lX\n", Packets_GetLastError());
        return -1;
    }

    TCHAR tszMsgBuffer[2048];
    LPCTSTR lpszMsgBuffer = _T("hello");
    NETENGINE_PROTOCOLHDR st_ProtocolHdr;
    int nLen = _tcslen(lpszMsgBuffer);
    int nMsgLen = 0;

    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(NETENGINE_PROTOCOLHDR));

    st_ProtocolHdr.wHeader = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER;
    st_ProtocolHdr.byIsReply = 1;
    st_ProtocolHdr.byVersion = 2;
    st_ProtocolHdr.unOperatorCode = NETENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_ISOK;
    st_ProtocolHdr.unOperatorType = ENUM_ENGINE_COMMUNICATION_PROTOCOL_TYPE_NORMAL;
    st_ProtocolHdr.unPacketSize = nLen;
    st_ProtocolHdr.wPacketSerial = 1;
    st_ProtocolHdr.wReserve = 0;
    st_ProtocolHdr.wTail = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL;

    memcpy(tszMsgBuffer, &st_ProtocolHdr, sizeof(NETENGINE_PROTOCOLHDR));
    memcpy(tszMsgBuffer + sizeof(NETENGINE_PROTOCOLHDR), lpszMsgBuffer, nLen);

    nMsgLen = sizeof(NETENGINE_PROTOCOLHDR) + nLen;

    HelpComponents_Datas_PostEx(xhPacket, lpszClientAddr, tszMsgBuffer, 10);
    HelpComponents_Datas_PostEx(xhPacket, lpszClientAddr, tszMsgBuffer + 10, 15);
    HelpComponents_Datas_PostEx(xhPacket, lpszClientAddr, tszMsgBuffer + 25, 10);

    HelpComponents_Datas_PostEx(xhPacket, lpszClientAddr, tszMsgBuffer, 35);
    nMsgLen = 2048;
    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(NETENGINE_PROTOCOLHDR));

    TCHAR tszClientAddr[64];
    memset(tszClientAddr, '\0', sizeof(tszClientAddr));
    HelpComponents_Datas_WaitEventEx(xhPacket);
    HelpComponents_Datas_GetRandomEx(xhPacket, tszClientAddr, tszMsgBuffer, &nMsgLen, &st_ProtocolHdr);
    printf("%d=%s\n", nMsgLen, tszMsgBuffer);

    nMsgLen = 2048;
    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(NETENGINE_PROTOCOLHDR));
    HelpComponents_Datas_WaitEventEx(xhPacket);
    HelpComponents_Datas_GetRandomEx(xhPacket, tszClientAddr, tszMsgBuffer, &nMsgLen, &st_ProtocolHdr);
    printf("%d=%s\n", nMsgLen, tszMsgBuffer);

    HelpComponents_Datas_WaitEventEx(xhPacket, 5000);
    HelpComponents_Datas_DeleteEx(xhPacket, lpszClientAddr);
    HelpComponents_Datas_Destory(xhPacket);
    return 0;
}
int Test_PacketPool()
{
    XNETHANDLE xhPacket;
    LPCTSTR lpszClientAddr = _T("127.0.0.1");
    if (!HelpComponents_Datas_Init(&xhPacket, 10000, 0, 4))
    {
        printf("HelpComponents_Datas_Init:%lX\n", Packets_GetLastError());
        return -1;
    }
    if (!HelpComponents_Datas_CreateEx(xhPacket, lpszClientAddr, 1))
    {
        printf("HelpComponents_Datas_CreateEx:%lX\n", Packets_GetLastError());
        return -1;
    }

    TCHAR tszMsgBuffer[2048];
    LPCTSTR lpszMsgBuffer = _T("hello");
    NETENGINE_PROTOCOLHDR st_ProtocolHdr;
    int nLen = _tcslen(lpszMsgBuffer);
    int nMsgLen = 0;

    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(NETENGINE_PROTOCOLHDR));

    st_ProtocolHdr.wHeader = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER;
    st_ProtocolHdr.byIsReply = 1;
    st_ProtocolHdr.byVersion = 2;
    st_ProtocolHdr.unOperatorCode = NETENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_ISOK;
    st_ProtocolHdr.unOperatorType = ENUM_ENGINE_COMMUNICATION_PROTOCOL_TYPE_NORMAL;
    st_ProtocolHdr.unPacketSize = nLen;
    st_ProtocolHdr.wPacketSerial = 1;
    st_ProtocolHdr.wReserve = 0;
    st_ProtocolHdr.wTail = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL;

    memcpy(tszMsgBuffer, &st_ProtocolHdr, sizeof(NETENGINE_PROTOCOLHDR));
    memcpy(tszMsgBuffer + sizeof(NETENGINE_PROTOCOLHDR), lpszMsgBuffer, nLen);

    nMsgLen = sizeof(NETENGINE_PROTOCOLHDR) + nLen;

    HelpComponents_Datas_PostEx(xhPacket, lpszClientAddr, tszMsgBuffer, 10);
    HelpComponents_Datas_PostEx(xhPacket, lpszClientAddr, tszMsgBuffer + 10, 15);
    HelpComponents_Datas_PostEx(xhPacket, lpszClientAddr, tszMsgBuffer + 25, 10);

    nMsgLen = 2048;
    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(NETENGINE_PROTOCOLHDR));

    TCHAR tszClientAddr[64];
    memset(tszClientAddr, '\0', sizeof(tszClientAddr));
    HelpComponents_Datas_WaitEventEx(xhPacket, 1);
    list<tstring> stl_ListAddr;

    HelpComponents_Datas_GetPoolEx(xhPacket, 1, &stl_ListAddr);
    list<tstring>::const_iterator stl_ListIterator = stl_ListAddr.begin();
    for (; stl_ListIterator != stl_ListAddr.end(); stl_ListIterator++)
    {
        HelpComponents_Datas_GetEx(xhPacket, stl_ListIterator->c_str(), tszMsgBuffer, &nMsgLen, &st_ProtocolHdr);
        printf("%d=%s\n", nMsgLen, tszMsgBuffer);
    }
    HelpComponents_Datas_WaitEventEx(xhPacket, 1, 5000);
    HelpComponents_Datas_DeleteEx(xhPacket, lpszClientAddr);
    HelpComponents_Datas_Destory(xhPacket);
    return 0;
}

typedef struct
{
    BYTE byStart;
    BYTE byCode;
    WORD wLen;
}HELPCOMONENTS_CUSTOMHDR;
typedef struct
{
    BYTE byCheck;
    BYTE byEnd;
}HELPCOMONENTS_CUSTOMTAIL;
int Test_PacketCustom()
{
    XNETHANDLE xhPacket;
    SOCKET hSocket = 1000;
    if (!HelpComponents_PKTCustom_Init(&xhPacket))
    {
        printf("HelpComponents_PKTCustom_Init:%lX\n", Packets_GetLastError());
        return -1;
    }
    HelpComponents_PKTCustom_SetHdrEx(xhPacket, 2, 4, sizeof(HELPCOMONENTS_CUSTOMHDR), TRUE);
    HelpComponents_PKTCustom_SetTailEx(xhPacket, sizeof(HELPCOMONENTS_CUSTOMTAIL));

    if (!HelpComponents_PKTCustom_CreateEx(xhPacket, hSocket))
    {
        printf("HelpComponents_PKTCustom_CreateEx:%lX\n", Packets_GetLastError());
        return -1;
    }

    TCHAR tszMsgBuffer[2048];
    LPCTSTR lpszMsgBuffer = _T("hello");
    HELPCOMONENTS_CUSTOMHDR st_ProtocolHdr;
    HELPCOMONENTS_CUSTOMTAIL st_ProtocolTail;

    int nLen = _tcslen(lpszMsgBuffer);
    int nMsgLen = 0;

    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(HELPCOMONENTS_CUSTOMHDR));
    memset(&st_ProtocolTail, '\0', sizeof(HELPCOMONENTS_CUSTOMTAIL));

    st_ProtocolHdr.byStart = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER;
    st_ProtocolHdr.byCode = ENUM_ENGINE_COMMUNICATION_PROTOCOL_TYPE_NORMAL;
    st_ProtocolHdr.wLen = htons(nLen);

    st_ProtocolTail.byCheck = 'E';
    st_ProtocolTail.byEnd = NETENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL;

    memcpy(tszMsgBuffer, &st_ProtocolHdr, sizeof(HELPCOMONENTS_CUSTOMHDR));
    memcpy(tszMsgBuffer + sizeof(HELPCOMONENTS_CUSTOMHDR), lpszMsgBuffer, nLen);
    memcpy(tszMsgBuffer + sizeof(HELPCOMONENTS_CUSTOMHDR) + nLen, &st_ProtocolTail, sizeof(HELPCOMONENTS_CUSTOMTAIL));

    nMsgLen = sizeof(NETENGINE_PROTOCOLHDR) + sizeof(HELPCOMONENTS_CUSTOMTAIL) + nLen;

    HelpComponents_PKTCustom_PostEx(xhPacket, hSocket, tszMsgBuffer, 2);
    HelpComponents_PKTCustom_PostEx(xhPacket, hSocket, tszMsgBuffer + 2, 2);
    HelpComponents_PKTCustom_PostEx(xhPacket, hSocket, tszMsgBuffer + 4, 5);
    HelpComponents_PKTCustom_PostEx(xhPacket, hSocket, tszMsgBuffer + 9, 2);

    nMsgLen = 2048;
    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    memset(&st_ProtocolHdr, '\0', sizeof(HELPCOMONENTS_CUSTOMHDR));
    memset(&st_ProtocolTail, '\0', sizeof(HELPCOMONENTS_CUSTOMTAIL));

    list<HELPCOMPONENT_PACKET_CLIENT> stl_ListClient;
    HelpComponents_PKTCustom_GetListEx(xhPacket, &stl_ListClient, 4, 4);
    list<HELPCOMPONENT_PACKET_CLIENT>::const_iterator stl_ListIterator = stl_ListClient.begin();
    for (; stl_ListIterator != stl_ListClient.end(); stl_ListIterator++)
    {
        HelpComponents_PKTCustom_GetEx(xhPacket, stl_ListIterator->hSocket, tszMsgBuffer, &nMsgLen, &st_ProtocolHdr, &st_ProtocolTail);
        printf("%d=%s\n", nMsgLen, tszMsgBuffer);
    }
    HelpComponents_PKTCustom_WaitEventEx(xhPacket, 1, 5000);
    HelpComponents_PKTCustom_DeleteEx(xhPacket, hSocket);
    HelpComponents_PKTCustom_Destory(xhPacket);
    return 0;
}
int main()
{
    Test_PacketCustom();
    Test_PacketPool();
    Test_Packets();
    Test_Datas();
    return 0;
}
